package com.kehutong.tag.service;

import com.kehutong.common.entity.Root;
import com.kehutong.crm.enums.TagSourceType;
import com.kehutong.tag.dao.UserTagDao;
import com.kehutong.tag.entity.CustomizeTag;
import com.kehutong.tag.entity.TemplateTag;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONObject;
import org.coraframework.logger.Logger;
import org.coraframework.logger.LoggerFactory;
import org.coraframework.mvc.http.Bean;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.mvc.webservice.WebService;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.Condition;
import org.coraframework.orm.jdbc.execute.PageCondition;
import org.coraframework.orm.jdbc.execute.QueryCondition;
import org.coraframework.orm.jdbc.execute.entity.FindArray;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.IDGenerate;
import org.coraframework.util.Objects;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 自定义标签服务类
 *
 * @author: liukunlong
 * @date: 2021-07-28 10:08
 */
@WebService("/crm/customize/tag/service")
public class CustomizeTagService {

    static final Logger logger = LoggerFactory.getLogger(CustomizeTagService.class);


    @Inject
    private JdbcSession jdbcSession;

    @Inject
    private UserTagDao userTagDao;

    /**
     * 根据条件获取标签列表
     *
     * @param jsonObject 查询对象
     * @return 标签列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/page")
    public Page<CustomizeTag> page(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<CustomizeTag> result = null;
        FindPage<CustomizeTag> findPage = jdbcSession.findPage(CustomizeTag.class)
                .eq(jsonObject, "id", "pid")
                .like(jsonObject, "name")
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc")
                .page(jsonObject);
        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<CustomizeTag> customizeTagList = result.getList();
            //设置标签的标签组名称及使用标签用户数
            for (CustomizeTag customizeTag : customizeTagList) {
                QueryCondition query = Condition.createQuery(false);
                query.eq("deleted", false);
                query.order("createTime", "desc");
                query.eq("tagNo", customizeTag.getId());
                Map<String, Object> countMap = userTagDao.getUserTagCount(query);
                customizeTag.setUseCount(Long.parseLong(String.valueOf(countMap.get("count"))));
                CustomizeTag customizeTagGroup = jdbcSession.findById(CustomizeTag.class, customizeTag.getPid());
                if (Objects.nonNull(customizeTagGroup)) {
                    customizeTag.setPname(customizeTagGroup.getName());
                } else {
                    customizeTag.setPname("");
                }
            }
        }
        return result;
    }

    /**
     * 获取标签列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/list")
    public Object list(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<CustomizeTag> page = page(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签内容
     *
     * @param customizeTag 标签对象
     * @return
     */
    @ReqMapping("/get")
    public Object get(CustomizeTag customizeTag) {
        return customizeTag;
    }

    /**
     * 保存标签
     *
     * @param customizeTag 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/save")
    public Object save(CustomizeTag customizeTag) {
        String id = customizeTag.getId();
        CustomizeTag dbCustomizeTag = jdbcSession.findOne(CustomizeTag.class)
                .eq("deleted", false)
                .eq("group", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", customizeTag.getName()).or()
                .markEnd().exe();
        customizeTag.setType(TagSourceType.CUSTOMIZE_TAG);
        customizeTag.setCreateBy(customizeTag.getCreateBy());
        customizeTag.setCreateName(customizeTag.getCreateName());
        if (Objects.isNull(dbCustomizeTag)) {
            customizeTag.setGroup(false);
            customizeTag.setType(TagSourceType.CUSTOMIZE_TAG);
            customizeTag.setSort(System.currentTimeMillis());
            jdbcSession.insert(customizeTag);
        } else {
            //如果创建的标签已经存在则更新标签信息,增加共创人信息
            List<String> commonCreateBy = dbCustomizeTag.getCommonCreateBy();
            List<String> commonCreateName = dbCustomizeTag.getCommonCreateName();
            if (Objects.isEmpty(commonCreateBy)) {
                commonCreateBy = new ArrayList<>();
                commonCreateName = new ArrayList<>();
            }
            if(!commonCreateBy.contains(customizeTag.getCreateBy())){
                commonCreateBy.add(customizeTag.getCreateBy());
                commonCreateName.add(customizeTag.getCreateName());
                dbCustomizeTag.setCommonCreateBy(commonCreateBy);
                dbCustomizeTag.setCommonCreateName(commonCreateName);
                dbCustomizeTag.setName(customizeTag.getName());
                jdbcSession.updateById(dbCustomizeTag);
            }
        }
        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param customizeTag 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/update")
    public Object update(CustomizeTag customizeTag) throws Exception {
        String id = customizeTag.getId();
        CustomizeTag dbCustomizeTag = jdbcSession.findOne(CustomizeTag.class)
                .eq("group", false)
                .eq("deleted", false)
                .eq("id",id).exe();
        if (Objects.isNull(dbCustomizeTag)) {
            return Result.success("0", "标签不存在");
        }
        jdbcSession.updateById(customizeTag);
        return Result.success();
    }


    /**
     * 删除标签
     *
     * @param customizeTag 标签对象
     * @return
     */
    @ReqMapping("/delete")
    public Object delete(CustomizeTag customizeTag) {
        customizeTag.setDeleted(true);
        jdbcSession.updateById(customizeTag);
        return Result.success();
    }

    /**
     * 根据条件获取标签组分页列表
     *
     * @param jsonObject 查询对象
     * @return 住户汽车列表
     * @throws IOException 操作异常
     */
    @ReqMapping("/group/page")
    public Page<CustomizeTag> groupPage(JSONObject jsonObject) throws Exception {
        String tagName = jsonObject.getString("tagName");

        Page<CustomizeTag> result = null;
        FindPage<CustomizeTag> findPage = jdbcSession.findPage(CustomizeTag.class)
                .eq(jsonObject, "id")
                .like(jsonObject, "name")
                .eq("group", true)
                .eq("deleted", false)
                //.order("sort", "desc")
                .page(jsonObject);
        String sort=jsonObject.getString("sort");
        if(Objects.isEmpty(sort)){
            findPage.order("sort", "desc");
        }else{
            findPage.order("sort",sort);
        }
        if (Objects.nonEmpty(tagName)) {
            List<CustomizeTag> customizeTagList = jdbcSession.findArray(CustomizeTag.class)
                    .eq("group", false)
                    .eq("deleted", false)
                    .like("name", tagName).exe();
            List<String> ids = customizeTagList.stream().map(CustomizeTag::getPid).collect(Collectors.toList());
            if (Objects.nonEmpty(ids)) {
                findPage.in("id", ids);
            }
        }
        //自定义标签数据权限
        String createBy = jsonObject.getString("createBy");
        jsonObject.getString("commonCreateBy");
        if (Objects.nonEmpty(createBy)) {
            findPage.markBegin()
                    .eq("createBy", createBy).or()
                    .eq("commonCreateBy", createBy).or();
            findPage.markEnd();
        }

        result = findPage.exe();
        if (logger.isDebugEnabled()) {
            logger.debug("result:" + result);
        }
        if (Objects.nonNull(result)) {
            List<CustomizeTag> customizeTagGroupList = result.getList();
            for (CustomizeTag customizeGroupTag : customizeTagGroupList) {
                FindArray<CustomizeTag> findCustomizeTagArray = jdbcSession.findArray(CustomizeTag.class)
                        .eq("pid", customizeGroupTag.getId())
                        .eq("group", false)
                        .eq("deleted", false)
                        .order("sort", "desc");

                //增加标签的数据权限
                if (Objects.nonEmpty(createBy)) {
                    findCustomizeTagArray.markBegin()
                            .eq("createBy", createBy).or()
                            .eq("commonCreateBy", createBy).or();
                    findCustomizeTagArray.markEnd();
                }
                List<CustomizeTag> customizeTagList = findCustomizeTagArray.exe();
                //设置标签的组名称
                for (CustomizeTag customizeTag : customizeTagList) {
                    customizeTag.setPname(customizeGroupTag.getName());
                }
                customizeGroupTag.setChildList(customizeTagList);
            }
        }
        return result;
    }

    /**
     * 根据条件获取标签组列表
     *
     * @param jsonObject 查询对象
     * @return
     * @throws Exception
     */
    @ReqMapping("/group/list")
    public Object groupList(JSONObject jsonObject) throws Exception {
        jsonObject.put("pageNo", 1);
        jsonObject.put("pageSize", Short.MAX_VALUE);
        Page<CustomizeTag> page = groupPage(jsonObject);
        return page.getList();
    }

    /**
     * 获取标签组
     *
     * @param customizeTagGroup 系统标签对象
     * @return
     */
    @ReqMapping("/group/get")
    public Object groupGet(CustomizeTag customizeTagGroup) {
        if (Objects.nonNull(customizeTagGroup)) {
            List<CustomizeTag> customizeTagList = jdbcSession.findArray(CustomizeTag.class)
                    .eq("pid", customizeTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            customizeTagGroup.setChildList(customizeTagList);

        }
        return customizeTagGroup;
    }

    /**
     * 保存自定义标签住标签组及标签
     *
     * @param customizeTagGroup 系统标签对象
     * @return
     */
    @Bean(newInstance = true, copy = true)
    @ReqMapping("/group/save")
    public Object groupSave(CustomizeTag customizeTagGroup) {
        String id = customizeTagGroup.getId();
        CustomizeTag dbCustomizeTagGroup = jdbcSession.findOne(CustomizeTag.class)
                .eq("deleted", false)
                .eq("group", true)
                .markBegin()
                .eq("id", id).or()
                .eq("name", customizeTagGroup.getName()).or()
                .markEnd().exe();
        customizeTagGroup.setType(TagSourceType.CUSTOMIZE_TAG);
        if (Objects.isNull(dbCustomizeTagGroup)) {
            customizeTagGroup.setPid(Root.ROOT_ID);
            customizeTagGroup.setGroup(true);
            customizeTagGroup.setType(TagSourceType.CUSTOMIZE_TAG);
            customizeTagGroup.setSort(System.currentTimeMillis());

            jdbcSession.insert(customizeTagGroup);
            List<CustomizeTag> customizeTagList = customizeTagGroup.getChildList();
            if (Objects.nonNull(customizeTagList)) {
                for (CustomizeTag customizeTag : customizeTagList) {
                    customizeTag.setId(IDGenerate.uuid());
                    customizeTag.setPid(customizeTagGroup.getId());
                    customizeTag.setGroup(false);
                    customizeTag.setType(TagSourceType.CUSTOMIZE_TAG);
                    customizeTag.setCreateBy(customizeTagGroup.getCreateBy());
                    customizeTag.setCreateName(customizeTagGroup.getCreateName());
                }
            }
            jdbcSession.insert(customizeTagList);
        } else {
            //如果创建的组已经存在则更新组信息,增加共创人信息
            List<String> commonCreateBy = dbCustomizeTagGroup.getCommonCreateBy();
            List<String> commonCreateName = dbCustomizeTagGroup.getCommonCreateName();
            String createBy = customizeTagGroup.getCreateBy();
            String createName = customizeTagGroup.getCreateName();
            String dbCreateBy = dbCustomizeTagGroup.getCreateBy();
            if (Objects.nonEmpty(createBy)) {
                if (!Objects.equal(createBy, dbCreateBy)) {
                    commonCreateBy.add(createBy);
                    commonCreateName.add(createName);
                    dbCustomizeTagGroup.setCommonCreateBy(commonCreateBy);
                    dbCustomizeTagGroup.setCommonCreateName(commonCreateName);
                }
            }
            dbCustomizeTagGroup.setName(customizeTagGroup.getName());
            jdbcSession.updateById(dbCustomizeTagGroup);

            //查询已存在的标签组下面不属于自己标签数据的数据(不是自己创建的数据,共创人也不是自己的数据)
            //数据库已存在的标签集合
            FindArray<CustomizeTag> findDbCustomizeTagList = jdbcSession.findArray(CustomizeTag.class)
                    .eq("pid", dbCustomizeTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc");
            List<CustomizeTag> dbCustomizeTagList = findDbCustomizeTagList.exe();

            //自定义标签名称与创建人的映射关系
            Map<String, String> customizeTagToCreateMapping = new LinkedHashMap<>();
            //自定义标签名称与标签对象映射关系
            Map<String, CustomizeTag> tagNameToTagMapping = new LinkedHashMap<>();
            for (CustomizeTag customizeTag : dbCustomizeTagList) {
                tagNameToTagMapping.put(customizeTag.getName(), customizeTag);
            }

            //插入自定义标签
            List<CustomizeTag> customizeTagList = customizeTagGroup.getChildList();
            if (Objects.nonNull(customizeTagList)) {
                for (CustomizeTag customizeTag : customizeTagList) {
                    //如果不存在相应标签则直接新增
                    if (!tagNameToTagMapping.containsKey(customizeTag.getName())) {
                        customizeTag.setId(IDGenerate.uuid());
                        customizeTag.setPid(customizeTagGroup.getId());
                        customizeTag.setGroup(false);
                        customizeTag.setCreateBy(customizeTagGroup.getCreateBy());
                        customizeTag.setCreateName(customizeTagGroup.getCreateName());
                        jdbcSession.insert(customizeTag);
                    } else {
                        CustomizeTag updateCustomizeTag = tagNameToTagMapping.get(customizeTag.getName());
                        //存在的标签的公创人中没有包含当前人则追加进去
                        if (!updateCustomizeTag.getCommonCreateBy().contains(customizeTagGroup.getCreateBy())) {
                            List<String> updateCommonCreateBy = updateCustomizeTag.getCommonCreateBy();
                            List<String> updateCommonCreateName = updateCustomizeTag.getCommonCreateName();
                            updateCommonCreateBy.add(createBy);
                            updateCommonCreateName.add(createName);
                            dbCustomizeTagGroup.setCommonCreateBy(commonCreateBy);
                            dbCustomizeTagGroup.setCommonCreateName(commonCreateName);
                            jdbcSession.updateById(dbCustomizeTagGroup);
                        }
                    }
                }
            }


        }

        return Result.success();
    }

    /**
     * 更新标签组及标签
     *
     * @param customizeTagGroup 系统标签对象
     * @return
     * @throws Exception
     */
    @Bean(copy = true)
    @ReqMapping("/group/update")
    public Object groupUpdate(CustomizeTag customizeTagGroup) throws Exception {
        String id = customizeTagGroup.getId();
        CustomizeTag dbCustomizeTagGroup = jdbcSession.findOne(CustomizeTag.class)
                .eq("deleted", false)
                .markBegin()
                .eq("id", id).or()
                .eq("name", customizeTagGroup.getName()).or()
                .markEnd().exe();
        if (Objects.isNull(dbCustomizeTagGroup)) {
            return Result.success("0", "标签组不存在");
        }
        jdbcSession.updateById(customizeTagGroup);


        //输入的标签集合
        List<CustomizeTag> customizeTagList = customizeTagGroup.getChildList();

        Map<String, CustomizeTag> mapping = new HashMap<>();
        for (CustomizeTag customizeTag : customizeTagList) {
            if (Objects.nonEmpty(customizeTag.getId())) {
                mapping.put(customizeTag.getId(), customizeTag);
            }
        }


        //数据库已存在的标签集合
        FindArray<CustomizeTag> findDbCustomizeTagList = jdbcSession.findArray(CustomizeTag.class)
                .eq("pid", dbCustomizeTagGroup.getId())
                .eq("group", false)
                .eq("deleted", false)
                .order("sort", "desc");
        //如果有创建人有权限的标签集合
        String createBy = customizeTagGroup.getCreateBy();
        if (Objects.nonEmpty(createBy)) {
            findDbCustomizeTagList.markBegin()
                    .eq("createBy", createBy).or()
                    .eq("commonCreateBy", createBy).or();
            findDbCustomizeTagList.markEnd();
        }
        List<CustomizeTag> dbCustomizeTagList = findDbCustomizeTagList.exe();

        //需要更新的标签集合
        List<CustomizeTag> updateCustomizeTagList = new ArrayList<>();

        //需要删除的标签集合
        List<CustomizeTag> deleteCustomizeTagList = new ArrayList<>();

        for (CustomizeTag dbCustomizeTag : dbCustomizeTagList) {
            String dbId = dbCustomizeTag.getId();
            if (mapping.containsKey(dbId)) {
                updateCustomizeTagList.add(mapping.get(dbId));
                customizeTagList.remove(dbCustomizeTag);
            } else {
                //如果当前标签是自己创建的则删除,否者去除公创人权限
                if (Objects.nonEmpty(createBy)) {
                    if (Objects.equal(createBy, dbCustomizeTag.getCreateBy())) {
                        deleteCustomizeTagList.add(dbCustomizeTag);
                    } else {
                        logger.info("没有实现移除共创人信息");
                        //TODO 移除共创人信息
                    }
                } else {
                    deleteCustomizeTagList.add(dbCustomizeTag);
                }
            }
        }

        //需要新增的标签集合
        List<CustomizeTag> addCustomizeTagList = new ArrayList<>(customizeTagList);

        //增量新增标签
        if (Objects.nonEmpty(addCustomizeTagList)) {
            for (CustomizeTag customizeTag : addCustomizeTagList) {
                customizeTag.setId(IDGenerate.uuid());
                customizeTag.setPid(dbCustomizeTagGroup.getId());
                customizeTag.setGroup(false);
                customizeTag.setType(TagSourceType.CUSTOMIZE_TAG);
                if (Objects.isEmpty(createBy)) {
                    customizeTag.setCreateBy(Root.ROOT_ID);
                    customizeTag.setCreateName("系统");
                } else {
                    customizeTag.setCreateBy(customizeTagGroup.getCreateBy());
                    customizeTag.setCreateName(customizeTagGroup.getCreateName());
                }
            }
            jdbcSession.insert(addCustomizeTagList);
        }

        //增量更新标签
        if (Objects.nonEmpty(updateCustomizeTagList)) {
            jdbcSession.updateById(updateCustomizeTagList);
        }

        //增量删除标签
        if (Objects.nonEmpty(deleteCustomizeTagList)) {
            for (CustomizeTag customizeTag : deleteCustomizeTagList) {
                customizeTag.setDeleted(true);
            }
            jdbcSession.updateById(deleteCustomizeTagList);
        }
        return Result.success();
    }


    /**
     * 删除标签组及标签
     *
     * @param customizeTagGroup 系统标签组对象
     * @return
     */
    @ReqMapping("/group/delete")
    public Object groupDelete(CustomizeTag customizeTagGroup) {
        customizeTagGroup.setDeleted(true);
        jdbcSession.updateById(customizeTagGroup);
        if (customizeTagGroup.isGroup()) {
            List<CustomizeTag> customizeTagList = jdbcSession.findArray(CustomizeTag.class)
                    .eq("pid", customizeTagGroup.getId())
                    .eq("group", false)
                    .eq("deleted", false)
                    .order("sort", "desc")
                    .exe();
            if (Objects.nonEmpty(customizeTagList)) {
                for (CustomizeTag customizeTag : customizeTagList) {
                    customizeTag.setDeleted(true);
                }
                jdbcSession.updateById(customizeTagList);
            }
        }
        return Result.success();
    }


}
